#!/bin/bash

# =============================================================================
# Admin服务重启脚本
# 作者: AI Assistant
# 创建时间: $(date +%Y-%m-%d)
# =============================================================================

# 配置参数
JAR_FOLDER="/mydata/jars/yccloud17/admin"
JAR_NAME="admin-0.0.1-SNAPSHOT.jar"
JAR_PATH="$JAR_FOLDER/$JAR_NAME"
LOG_FILE="$JAR_FOLDER/admin.log"
PID_FILE="$JAR_FOLDER/admin.pid"
APPLICATION_YML="$JAR_FOLDER/application.yml"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

# 检查Java运行环境
check_java() {
    if ! command -v java &> /dev/null; then
        log_error "Java未安装或不在PATH中"
        exit 1
    fi
    log_info "Java环境检查通过"
}

# 检查JAR文件
check_jar() {
    if [ ! -f "$JAR_PATH" ]; then
        log_error "JAR文件不存在: $JAR_PATH"
        exit 1
    fi
    log_info "JAR文件检查通过: $JAR_PATH"
}

# 停止服务
stop_service() {
    local PID=""
    
    # 获取PID
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
    else
        PID=$(pgrep -f "$JAR_NAME")
    fi
    
    if [ -z "$PID" ]; then
        log_warn "未发现运行中的服务"
        return 0
    fi
    
    log_info "停止Admin服务 (PID: $PID)..."
    
    # 尝试优雅停止
    kill -TERM "$PID"
    
    # 等待进程优雅退出
    local TIMEOUT=30
    while [ $TIMEOUT -gt 0 ]; do
        if ! ps -p "$PID" > /dev/null 2>&1; then
            log_info "服务已优雅停止"
            break
        fi
        sleep 1
        ((TIMEOUT--))
    done
    
    # 如果优雅停止失败，强制停止
    if [ $TIMEOUT -eq 0 ]; then
        log_warn "优雅停止超时，强制停止..."
        kill -KILL "$PID"
        sleep 2
    fi
    
    # 清理PID文件
    if [ -f "$PID_FILE" ]; then
        rm -f "$PID_FILE"
        log_info "已清理PID文件"
    fi
    
    # 最终检查
    if pgrep -f "$JAR_NAME" > /dev/null 2>&1; then
        log_error "服务停止失败"
        return 1
    fi
    
    log_info "服务停止成功"
    return 0
}

# 启动服务
start_service() {
    log_info "启动Admin服务..."
    
    # 创建必要目录
    mkdir -p "$JAR_FOLDER"
    
    # 构建启动命令
    START_CMD="nohup java -jar"
    
    # JVM参数
    JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError"
    START_CMD="$START_CMD $JVM_OPTS"
    
    # 配置文件
    if [ -f "$APPLICATION_YML" ]; then
        START_CMD="$START_CMD --spring.config.location=$APPLICATION_YML"
        log_info "使用配置文件: $APPLICATION_YML"
    else
        log_warn "配置文件不存在，使用默认配置"
    fi
    
    # 完整启动命令
    START_CMD="$START_CMD $JAR_PATH >> $LOG_FILE 2>&1 & echo \$! > $PID_FILE"
    
    # 执行启动
    eval $START_CMD
    
    # 等待启动
    sleep 5
    
    # 检查启动状态
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p "$PID" > /dev/null 2>&1; then
            log_info "服务启动成功！PID: $PID"
            log_info "日志文件: $LOG_FILE"
            return 0
        fi
    fi
    
    log_error "服务启动失败，请检查日志: $LOG_FILE"
    return 1
}

# 等待服务就绪
wait_for_service() {
    log_info "等待服务就绪..."
    
    local TIMEOUT=60
    local count=0
    
    while [ $count -lt $TIMEOUT ]; do
        # 检查进程是否还在运行
        if [ -f "$PID_FILE" ]; then
            PID=$(cat "$PID_FILE")
            if ! ps -p "$PID" > /dev/null 2>&1; then
                log_error "服务进程已死亡"
                return 1
            fi
        fi
        
        # 检查端口是否监听（这里假设默认端口8080，实际端口请根据配置调整）
        if netstat -tlnp 2>/dev/null | grep ":8080 " > /dev/null; then
            log_info "服务已就绪，端口8080正在监听"
            return 0
        fi
        
        sleep 2
        ((count += 2))
        
        if [ $((count % 10)) -eq 0 ]; then
            log_warn "等待服务就绪... (${count}s/${TIMEOUT}s)"
        fi
    done
    
    log_warn "服务启动超时，但进程仍在运行"
    return 0
}

# 主函数
main() {
    log_info "开始重启Admin服务..."
    
    # 检查环境
    check_java
    check_jar
    
    # 停止服务
    if ! stop_service; then
        log_error "停止服务失败，重启终止"
        exit 1
    fi
    
    # 等待一段时间确保端口释放
    sleep 3
    
    # 启动服务
    if ! start_service; then
        log_error "启动服务失败，重启终止"
        exit 1
    fi
    
    # 等待服务就绪
    if wait_for_service; then
        log_info "Admin服务重启完成！"
        exit 0
    else
        log_error "Admin服务重启失败！"
        exit 1
    fi
}

# 执行主函数
main "$@"
